#include "var.h"
#include "operator.h"
#include "constant.h"
#include "template.h"

Var::Var(const QString& name, Node* expr, const Type& type, const YYLTYPE& loc)
        : Node(loc), m_name(name), m_expr(expr), m_type(type)
{
    appendChild(expr);
}

bool Var::isConstant() const
{
    return isConstant(this);
}

bool Var::isConstant(const Node* n)
{
    if ( dynamic_cast<const Var*>(n) )
    {
    }
    else if ( dynamic_cast<const Constant*>(n) )
    {
        const Constant* c = dynamic_cast<const Constant*>(n);
        switch( c->kind() )
        {
        case Constant::Int:
        case Constant::Float:
        case Constant::String:
        case Constant::True:
        case Constant::False:
        case Constant::Null:
            return true;
        case Constant::VariableIdentifier:
            {
                const Template* t = dynamic_cast<const Template*>(c->resolvedNode());
                if ( t )
                    return true;
                const Var *v = dynamic_cast<const Var*>(c->resolvedNode());
                if ( !v || !v->isConstant() )
                    return false;
                return true;
            }
        default:
            return false;
        }
    }
    else if ( !dynamic_cast<const Operator*>(n) )
        return false;

    const Node* p = n->firstChild();
    while( p )
    {
        if ( !isConstant(p) )
            return false;
        p = p->nextSibling();
    }

    return true;
}
